<script setup lang="ts">
import { isFullWidthCharacter } from '@/utils/isFullWidthChar'

import cheveronYIcon from '@/static/images/cheveron-y.png'
import cheveronYGrayIcon from '@/static/images/cheveron-y-gray.png'
import { CouponClassification, CouponType } from '@/types/enum'

const props = withDefaults(defineProps<{
  name?: string
  price?: string
  discountRate?: string
  minisum: string
  classificate: CouponClassification // 1新人券 2员工券 3普通券 4洗牙券 5定额券
  type: CouponType // 1满减券 2折扣券 3洗牙券 4定额券
  period: {
    start: string
    end: string
  }
  tip: string
  id: string
  owned: boolean
  expired?: boolean
  validated?: boolean
}>(), {
  expired: false,
})

defineEmits(['use', 'claim'])

const expanded = ref(false)

const classificateName = computed(() => {
  return [
    '新人券',
    '员工券',
    '普通券',
    '洗牙券',
    '定额券',
  ][props.classificate - 1]
})

/**
 * 满减 -> 显示 金额 + 满xxx元可用
 * 折扣 -> 显示 几折 + 满xxx元可用
 * 定额 -> 显示 金额
 * 1张 -> 显示 1张
 */
type DisplayType = '满减' | '折扣' | '定额' | '1张'

/**
 * @description 根据 type 和 classifate 字段判断优惠券的显示样式。
 * （黑魔法）这样做的原因是 2024.04.15 新增了 洗牙券 和 定额券，
 * 后端返回的 classifate 和 type 字段定义不明确，有一些混乱，
 * 根据 classifate 判断 洗牙券 和 定额券 是安全的，
 * 根据 type 判断 满减券 和 折扣券 也是安全的。
 */
const displayType = computed<DisplayType | undefined>(() => {
  if (props.classificate === CouponClassification.洗牙券)
    return '1张'
  if (props.classificate === CouponClassification.定额券)
    return '定额'
  if (props.type === CouponType.满减券)
    return '满减'
  if (props.type === CouponType.折扣券)
    return '折扣'
})

/**
 * @description 定额券的 money 字段和 complete_money 字段是反的，money 字段表示券额
 */
const displayPrice = computed(() => {
  if (props.classificate === CouponClassification.定额券)
    return props.minisum
  return props.price
})

function getTipTotalWidth() {
  let width = 0
  Array.from(props.tip).forEach((char) => {
    if (isFullWidthCharacter(char))
      width += uni.upx2px(11 + 8)
    else
      width += uni.upx2px(22 + 8)
  })
  return width
}

function getTipLineNumber() {
  return getTipTotalWidth() / 662
}

function getTipContainerHeight() {
  return getTipLineNumber() * 30 + uni.upx2px(116)
}

function getMainContainerHeight() {
  return getTipLineNumber() * 30 + uni.upx2px(305)
}
</script>

<template>
  <!-- 容器 -->
  <view class="relative mb-24rpx overflow-hidden overflow-hidden rounded-20rpx transition-all duration-250 ease-in-out" :style="{ height: expanded ? `${getMainContainerHeight()}px` : '210rpx' }">
    <!-- 优惠券卡片部分 -->
    <view class="absolute top-0 z-2 h-210rpx flex items-center overflow-hidden x-center">
      <!-- 优惠券卡片左侧 -->
      <view
        class="h-210rpx w-542rpx flex flex-col justify-between rounded-l-20rpx p-20rpx pt-26rpx"
        :class="[
          expired ? 'text-#BDBDBD' : 'text-#FF5555',
          expired ? 'bg-white' : 'bg-#FFF1F1',
        ]"
      >
        <!-- 左侧上半 金额等信息 -->
        <view class="flex">
          <Spacer width="28" />
          <view class="flex flex-shrink-0 flex-col items-center justify-center">
            <!-- 满减券或定额券直接显示券面金额 -->
            <view v-if="displayType === '满减' || displayType === '定额'" class="flex flex-shrink-0 items-baseline">
              <view class="text-42rpx font-semibold">
                ¥
              </view>
              <view class="text-80rpx font-semibold leading-80rpx">
                {{ parseInt(displayPrice!) || '0' }}
              </view>
            </view>
            <!-- 折扣券显示几折 -->
            <view v-else-if="displayType === '折扣'">
              <view class="flex-shrink-0 text-80rpx font-semibold leading-80rpx">
                {{ `${props.discountRate || '0'}折` }}
              </view>
            </view>
            <!-- 洗牙券显示“1张”（2024.04.15新增） -->
            <view v-else-if="displayType === '1张'">
              <view class="flex-shrink-0 text-80rpx font-semibold leading-80rpx">
                1张
              </view>
            </view>
            <!-- 满减券或折扣券显示 满xx元可用 -->
            <block v-if="props.type === CouponType.满减券 || props.type === CouponType.折扣券">
              <Spacer height="6" />
              <view class="text-20rpx font-semibold leading-28rpx">
                满{{ minisum || '0' }}元可用
              </view>
            </block>
          </view>
          <Spacer width="38" />
          <view
            class="w-1px bg-opacity-20"
            :class="[expired ? 'bg-#BDBDBD' : 'bg-#FF5555']"
          />
          <Spacer width="38" />
          <view>
            <view class="text-30rpx font-semibold leading-42rpx">
              {{ name || classificateName }}
            </view>
            <Spacer height="8" />
            <view class="text-24rpx font-semibold leading-32rpx">
              有效期
            </view>
            <view class="text-24rpx font-semibold leading-32rpx">
              {{ `${period.start}-${period.end}` }}
            </view>
          </view>
        </view>
        <!-- 左侧下半 缩略提示 -->
        <view class="w-485rpx flex items-center" @tap="expanded = !expanded">
          <view class="truncate text-18rpx leading-25rpx">
            {{ tip }}
          </view>
          <Spacer width="16" />
          <image
            class="h-12rpx w-20rpx flex-shrink-0 transition-all duration-250 ease-in-out"
            :style="{ transform: !expanded ? 'rotate(180deg)' : undefined }"
            :src="expired ? cheveronYGrayIcon : cheveronYIcon"
          />
        </view>
      </view>
      <!-- 优惠券卡片右侧 -->
      <view
        v-if="!expired"
        class="h-210rpx w-160rpx flex items-center justify-center rounded-r-20rpx from-#FF5555 to-#FF8686 bg-gradient-to-tl"
        @tap="owned ? $emit('use') : $emit('claim')"
      >
        <view class="w-60rpx text-30rpx text-white font-semibold leading-32rpx">
          {{ owned ? '立即使用' : '立即领取' }}
        </view>
      </view>
      <view v-else class="relative h-210rpx w-160rpx bg-white">
        <image
          v-if="expired && validated"
          class="absolute right-24rpx top-24rpx h-105rpx w-105rpx"
          src="@/static/images/validated.png"
        />
        <image
          v-else
          class="absolute right-24rpx top-24rpx h-105rpx w-105rpx"
          src="@/static/images/expired.png"
        />
      </view>
      <!-- 优惠券过期后展开时显示的分割线 -->
      <Divider
        class="absolute bottom-0 transition-opacity duration-250 ease-in-out x-center"
        width="662"
        color="#BDBDBD"
        :style="{ opacity: expired && expanded ? '1' : '0' }"
      />
      <!-- 两个半圆，看起来像裁掉了卡片 -->
      <view class="absolute right-154rpx h-10rpx w-10rpx rounded-full bg-#F8F8F8 -top-5rpx" />
      <view class="absolute right-154rpx h-10rpx w-10rpx rounded-full bg-#F8F8F8 -bottom-5rpx" />
    </view>
    <!-- 展开部分 -->
    <view class="absolute bottom-0 z-1 w-702rpx flex flex-col justify-between rounded-20rpx bg-white px-20rpx pb-28rpx pt-48rpx x-center" :style="{ height: `${getTipContainerHeight()}px` }">
      <view
        class="text-22rpx leading-30rpx"
        :class="[expired ? 'text-#BDBDBD' : 'text-#848484']"
      >
        {{ tip }}
      </view>
      <view
        class="text-22rpx leading-30rpx"
        :class="[expired ? 'text-#BDBDBD' : 'text-#848484']"
      >
        {{ `券编号：${id}` }}
      </view>
    </view>
  </view>
</template>
